﻿using FieldTools.Client.Command;
using FieldTools.Client.Model.Window;
using FieldTools.Util;
using HandyControl.Controls;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace FieldTools.Client.ViewModel.Window
{
    public class JSInterpreterViewModel : NotificationObject, ISingletonDependency
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cancellationToken"></param>
        public JSInterpreterViewModel()
        {
            obj = CacheHelper.GetOrSetCache("JSInterpreterModel", new JSInterpreterModel());
            Console.WriteLine("打开js解释器");
        }


        #region 实体

        /// <summary>
        /// Model对象
        /// </summary>
        private JSInterpreterModel obj = new();

        /// <summary>
        /// 文件路径
        /// </summary>
        public string? FilePath
        {
            get{ return obj.FilePath; }
            set { obj.FilePath = value; CacheHelper.SetCache("JSInterpreterModel", obj); this.RaisePropertyChanged(nameof(FilePath)); }
        }

        /// <summary>
        /// js字符串
        /// </summary>
        public string? JSStr
        {
            get { return obj.JSStr; }
            set { obj.JSStr = value; this.RaisePropertyChanged(nameof(JSStr)); }
        }

        /// <summary>
        /// js入口函数
        /// </summary>
        public string? JSEntFunc
        {
            get { return obj.JSEntFunc; }
            set { obj.JSEntFunc = value; CacheHelper.SetCache("JSInterpreterModel", obj); this.RaisePropertyChanged(nameof(JSEntFunc)); }
        }

        /// <summary>
        /// 参数，json格式
        /// </summary>
        public string? ParmsJSON
        {
            get { return obj.ParmsJSON; }
            set { obj.ParmsJSON = value; CacheHelper.SetCache("JSInterpreterModel", obj); this.RaisePropertyChanged(nameof(ParmsJSON)); }
        }

        /// <summary>
        /// 执行结果
        /// </summary>
        public string? Result
        {
            get { return obj.Result; }
            set { obj.Result = value; CacheHelper.SetCache("JSInterpreterModel", obj); this.RaisePropertyChanged(nameof(Result)); }
        }
        /// <summary>
        /// 参数模板参数数量
        /// </summary>
        public int? ParmsCount
        {
            get{ return obj.ParmsCount; }
            set { obj.ParmsCount = value; CacheHelper.SetCache("JSInterpreterModel", obj); this.RaisePropertyChanged(nameof(ParmsCount)); }
        }
        /// <summary>
        /// 参数生成模式，1 object，2 null
        /// </summary>
        public int? ParmsType
        {
            get { return obj.ParmsType; }
            set { obj.ParmsType = value; CacheHelper.SetCache("JSInterpreterModel", obj); this.RaisePropertyChanged(nameof(ParmsType)); }
        }

        #endregion

        #region 事件
        private BaseCommand openFile;
        /// <summary>
        /// 打开js文件
        /// </summary>
        public BaseCommand OpenFile
        {
            get
            {
                if (openFile == null)
                {
                    openFile = new BaseCommand(new Action<object>(o =>
                    {
                        FilePath = ChooseFile();
                        if (FilePath != null)
                        {
                            try
                            {
                                JSStr = File.ReadAllText(FilePath, Encoding.GetEncoding("utf-8")) ?? "";//读取文件
                            }
                            catch (Exception)
                            {
                                JSStr = "";
                            }
                        }
                    }));
                }
                return openFile;
            }
        }

        private BaseCommand runJS;
        /// <summary>
        /// 运行js
        /// </summary>
        public BaseCommand RunJS
        {
            get
            {
                if (runJS == null)
                {
                    runJS = new BaseCommand(new Action<object>(async o =>
                    {
                        Result = (await RunJSFromStr()).FormatJsonString();
                    }));
                }
                return runJS;
            }
        }
        private BaseCommand runJSX;
        /// <summary>
        /// 运行js
        /// </summary>
        public BaseCommand RunJSX
        {
            get
            {
                if (runJSX == null)
                {
                    runJSX = new BaseCommand(new Action<object>(async o =>
                    {
                        Result = (await RunJSFromFile()).FormatJsonString();
                    }));
                }
                return runJSX;
            }
        }
        private BaseCommand creatParmsTemplate;
        /// <summary>
        /// 生成js参数模板
        /// </summary>
        public BaseCommand CreatParmsTemplate
        {
            get
            {
                if (creatParmsTemplate == null)
                {
                    creatParmsTemplate = new BaseCommand(new Action<object>(o =>
                    {
                        ParmsJSON = CreatParmsTemplateJson();
                    }));
                }
                return creatParmsTemplate;
            }
        }

        private BaseCommand saveFile;
        /// <summary>
        /// 保存文件
        /// </summary>
        public BaseCommand SaveFile
        {
            get
            {
                if (saveFile == null)
                {
                    saveFile = new BaseCommand(new Action<object>(o =>
                    {
                        SaveJSFile();
                    }));
                }
                return saveFile;
            }
        }
        #endregion

        #region 方法
        //private readonly string testJSStr = "module.exports = (callback, message) => callback(null, { message: message });";
        private static string ChooseFile()
        {
            var ofd = new OpenFileDialog() { 
                Filter = "JS脚本文件|*.js|文本文件|*.txt",
                InitialDirectory = Environment.CurrentDirectory
            };
            if (ofd.ShowDialog()==true)
            {
                return ofd.FileName;
            }
            else
            {
                return "";
            }
        }

        private async Task<string> RunJSFromStr()
        {
            if (JSStr == "" || JSStr == null)
            {
                MessageBox.Show("无可执行内容，请输入或从文件中读取");
                return string.Empty;
            }
            var objs = new List<object>();
            try
            {
                Dictionary<string, object> dict = JsonExtention.DeserializeStringToDictionary<string, object>(ParmsJSON);
                var vv = dict.Values;
                dict.ForEach(v =>
                {
                    objs.Add(v.Value);
                });
            }
            catch (Exception ex)
            {
                if (!ParmsJSON.IsNullOrEmpty())
                {
                    Result = ex.Message;
                }
                //throw;
            }

            var parms = objs?.ToArray() ?? null;
            return await Util.JSHelper.RunJsFromStr(JSStr, null, JSEntFunc, parms) ?? string.Empty;
        }

        private async Task<string> RunJSFromFile()
        {
            if (FilePath == "" || FilePath == null)
            {
                MessageBox.Show("无可执行内容，请输入或从文件中读取");
                return string.Empty;
            }

            var parms = JsonExtention.DeserializeStringToObjectArray(ParmsJSON);
            //parms = new object[] { 11212, "ssssss" };
            //parms = JsonExtention.JsonToObjectList(ParmsJSON).ToArray();
            return await Util.JSHelper.RunJsFromFile(FilePath, JSEntFunc, parms) ?? string.Empty;
        }

        private string CreatParmsTemplateJson()
        {
            var js = "{\r\n";
            for (int i = 0; i < ParmsCount; i++)
            {
                var ii = "\t\"c" + (i + 1) + "\":";
                if (ParmsType == 1)
                {
                    ii += "{}";
                }
                else if (ParmsType == 2)
                {
                    ii += "null";
                }
                else if (ParmsType == 3)
                {
                    ii += "\"\"";
                }
                else
                {
                    return "{}";
                }
                if (i + 1 != ParmsCount) ii += ",";
                ii += "\r\n";
                js += ii;
            }
            js += "}";
            return js;
        }
        
        private void SaveJSFile()
        {
            //创建一个保存文件式的对话框
            SaveFileDialog sfd = new SaveFileDialog() {
                Filter = "JS文件|*.js|文本文件|*.txt",
                InitialDirectory = FilePath!="" ? FilePath : Environment.CurrentDirectory
            };
            //调用ShowDialog()方法显示该对话框，该方法的返回值代表用户是否点击了确定按钮
            if (sfd.ShowDialog() == true)
            {
                try
                {
                    File.WriteAllText(sfd.FileName, JSStr);//将内容写进jon文件中
                    MessageBox.Show("保存成功");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("保存失败："+ex.Message);
                }
            }
        }
        #endregion
    }
}
